﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GoblinXNA.Graphics.Geometry;
using GoblinXNA.SceneGraph;
using Microsoft.Xna.Framework;

namespace ARDominos
{
    class Transformator
    {
        private BranchNode _branchNode;
        //private float _epsilonZero = 0.00001f;
        private TransformNode _transformingTransformNode;
        private MarkerNode _cursorMarkerNode;
        private GeometryNode _geometryNode;

        public Transformator(BranchNode branchNode, MarkerNode cursorMarkerNode)
        {
            this._branchNode = branchNode;
            this._cursorMarkerNode = cursorMarkerNode;
        }

        public void Start(Matrix position)
        {
            foreach (Node node in this._branchNode.Children)
            {
                TransformNode transformNode = node as TransformNode;
                if (transformNode== null)
                    continue;
                GeometryNode geometryNode = transformNode.Children.First() as GeometryNode;
                // TODO: change object recognition to node.categoryid
                TexturedBox texturedBox = geometryNode.Model as TexturedBox;
                if (texturedBox != null)
                {
                    Vector3 dim = (Vector3) geometryNode.UserData;
                    Matrix positionGroundNode = new Matrix();
                    positionGroundNode = position;
                    Matrix positionBox = positionGroundNode * Matrix.Invert(transformNode.WorldTransformation);
                    // position of point in coordinates of box:
                    float x = positionBox.Translation.X;
                    float y = positionBox.Translation.Y;
                    float z = positionBox.Translation.Z;
                    // if point is insiade a box
                    if (Math.Abs(x) <= dim.X / 2.0f && Math.Abs(y) <= dim.Y / 2.0f && Math.Abs(z) <= dim.Z / 2.0f)
                    {
                        this._transformingTransformNode = transformNode;
                        this._geometryNode = geometryNode;
                        //todo: remove from transforamtion node/suspend
                        this._transformingTransformNode.RemoveChild(this._geometryNode);
                        this._cursorMarkerNode.AddChild(this._geometryNode);
                    }
                    continue;
                }
                TexturedSphere texturedSphere = geometryNode.Model as TexturedSphere;
                 if (texturedSphere != null)
                {
                    float r = texturedSphere.MinimumBoundingSphere.Radius;
                    float x = position.Translation.X;
                    float y = position.Translation.Y;
                    float z = position.Translation.Z;
                    float a = transformNode.WorldTransformation.Translation.X;
                    float b = transformNode.WorldTransformation.Translation.Y;
                    float c = transformNode.WorldTransformation.Translation.Z;
                    // if point is inside a sphere
                    if ((x - a) * (x - a) + (y - b) * (y - b) + (z - c) * (z - c) <= r * r )
                    {
                        this._transformingTransformNode = transformNode;
                        this._geometryNode = geometryNode;
                        this._transformingTransformNode.RemoveChild(this._geometryNode);
                        this._cursorMarkerNode.AddChild(this._geometryNode);
                    }
                    continue;
                }

            }
        }

        public void Stop(Matrix cursorTranslation)
        {
            if (this._transformingTransformNode != null)
            {//copy ?

                //this._branchNode.Children.Remove(this._transformingTransformNode);

                this._transformingTransformNode.WorldTransformation = cursorTranslation;
                this._cursorMarkerNode.RemoveChild(this._geometryNode);
                this._transformingTransformNode.AddChild(this._geometryNode);
                this._transformingTransformNode = null;
                this._geometryNode = null;
                //this._branchNode.Children.Add(this._transformingTransformNode);

            }
        }
    }
}
